package io.renren.common.utils;

/**
 * HTTP工具类
 */

import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import io.renren.common.base.OkHttpClientBuilder;
import io.renren.common.base.OkHttpClientResult;
import okhttp3.*;

import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

public class OkHttp3Util {
    /**
     * get请求
     *
     * @param url
     * @param headers
     * @return
     */
    public static String get(String url, Map<String, String> headers) {
        Request request = new Request.Builder()
                .url(url)
                .headers(buildHeaders(headers))
                .get()
                .build();
        OkHttpClientResult result = commonRequest(request);
        return buildResponse(result);
    }

    public static OkHttpClientResult getOkHttpClientResult(String url, Map<String, String> headers) {
        Request request = new Request.Builder()
                .url(url)
                .headers(buildHeaders(headers))
                .get()
                .build();
        return commonRequest(request);
    }

    /**
     * get请求（支持范型对象返回参数）
     *
     * @param url
     * @param headers
     * @param responseType
     * @param <T>
     * @return
     */
    public static <T> T get(String url, Map<String, String> headers, Class<T> responseType) {
        Request request = new Request.Builder()
                .url(url)
                .headers(buildHeaders(headers))
                .get()
                .build();
        OkHttpClientResult result = commonRequest(request);
        return buildResponse(result, responseType);
    }

    /**
     * post表单请求
     *
     * @param url
     * @param paramMap
     * @param headers
     * @return
     */
    public static String postByForm(String url, Map<String, String> paramMap, Map<String, String> headers) {
        Request request = new Request.Builder()
                .url(url)
                .headers(buildHeaders(headers))
                .post(buildFormBody(paramMap))
                .build();
        OkHttpClientResult result = commonRequest(request);
        return buildResponse(result);
    }

    /**
     * post表单请求（支持范型对象返回参数）
     *
     * @param url
     * @param paramMap
     * @param headers
     * @param responseType
     * @param <T>
     * @return
     */
    public static <T> T postByForm(String url, Map<String, String> paramMap, Map<String, String> headers, Class<T> responseType) {
        Request request = new Request.Builder()
                .url(url)
                .headers(buildHeaders(headers))
                .post(buildFormBody(paramMap))
                .build();
        OkHttpClientResult result = commonRequest(request);
        return buildResponse(result, responseType);
    }


    /**
     * post + json请求
     *
     * @param url
     * @param value
     * @param headers
     * @return
     */
    public static String postByJson(String url, Object value, Map<String, String> headers) {
        Request request = new Request.Builder()
                .url(url)
                .headers(buildHeaders(headers))
                .post(buildJsonBody(value))
                .build();
        //System.out.println(JSON.toJSONString(request));
        OkHttpClientResult result = commonRequest(request);
        return buildResponse(result);
    }

    public static String postByJsonStr(String url, String value, Map<String, String> headers) {
        Request request = new Request.Builder()
                .url(url)
                .headers(buildHeaders(headers))
                .post(buildJsonBodyStr(value))
                .build();
        //System.out.println(JSON.toJSONString(request));
        OkHttpClientResult result = commonRequest(request);
        return buildResponse(result);
    }

    /**
     * post + raw请求
     *
     * @param url       请求的URL
     * @param rawBody   原始请求体
     * @param headers   请求头
     * @param contentType 内容类型（如 application/json）
     * @return 响应结果
     */
    public static String postByRaw(String url, String rawBody, Map<String, String> headers, String contentType) {
        Request request = new Request.Builder()
                .url(url)
                .headers(buildHeaders(headers))
                .post(buildRawBody(rawBody, contentType))
                .build();
        OkHttpClientResult result = commonRequest(request);
        return buildResponse(result);
    }

    /**
     * 包装请求raw数据
     *
     * @param rawBody   原始请求体
     * @param contentType 内容类型（如 application/json）
     * @return RequestBody
     */
    private static RequestBody buildRawBody(String rawBody, String contentType) {
        MediaType mediaType = MediaType.parse(contentType);
        RequestBody requestBody = RequestBody.create(mediaType, rawBody);
        return requestBody;
    }

    /**
     * post + json请求,这里返回的是整个OkHttpClientResult
     *
     * @param url
     * @param value
     * @param headers
     * @return
     */
    public static OkHttpClientResult postOkHttpClientResult(String url, Object value, Map<String, String> headers) {
        Request request = new Request.Builder()
                .url(url)
                .headers(buildHeaders(headers))
                .post(buildJsonBody(value))
                .build();
        //System.out.println(JSON.toJSONString(request));
        return commonRequest(request);
    }


    /**
     * post + json请求（支持范型对象返回参数）
     *
     * @param url
     * @param value
     * @param headers
     * @param responseType
     * @param <T>
     * @return
     */
    public static <T> T postByJson(String url, Object value, Map<String, String> headers, Class<T> responseType) {
        Request request = new Request.Builder()
                .url(url)
                .headers(buildHeaders(headers))
                .post(buildJsonBody(value))
                .build();
        OkHttpClientResult result = commonRequest(request);
        return buildResponse(result, responseType);
    }


    /**
     * 包装请求头部
     *
     * @param headers
     * @return
     */
    private static Headers buildHeaders(Map<String, String> headers) {
        Headers.Builder headerBuilder = new Headers.Builder();
        if (MapUtil.isNotEmpty(headers)) {
            headers.entrySet().forEach(entry -> headerBuilder.add(entry.getKey(), entry.getValue()));
        }
        return headerBuilder.build();
    }


    /**
     * 包装请求表单
     *
     * @param paramMap
     * @return
     */
    private static FormBody buildFormBody(Map<String, String> paramMap) {
        FormBody.Builder formBodyBuilder = new FormBody.Builder();
        if (MapUtil.isNotEmpty(paramMap)) {
            paramMap.entrySet().forEach(entry -> formBodyBuilder.add(entry.getKey(), entry.getValue()));
        }
        return formBodyBuilder.build();
    }

    /**
     * 包装请求json数据
     *
     * @param request
     * @return
     */
    private static RequestBody buildJsonBody(Object request) {
        MediaType contentType = MediaType.parse("application/json; charset=utf-8");
        RequestBody requestBody = RequestBody.create(contentType, JSON.toJSONString(request));
        return requestBody;
    }

    private static RequestBody buildJsonBodyStr(String requestStr) {
        MediaType contentType = MediaType.parse("application/json; charset=utf-8");
        RequestBody requestBody = RequestBody.create(contentType, requestStr);
        return requestBody;
    }

    /**
     * 包装返回结果，针对字符串
     *
     * @param result
     * @return
     */
    public static String buildResponse(OkHttpClientResult result) {
        if (!result.isSuccess() && StrUtil.isNotBlank(result.getMessage())) {
            throw new RuntimeException(result.getMessage());
        }
        //System.out.println("body:" + result.getBody());
        return byteToString(result.getBody());
    }

    /**
     * 包装返回结果，针对返回范型对象
     *
     * @param result
     * @return
     */
    public static <T> T buildResponse(OkHttpClientResult result, Class<T> responseType) {
        if (!result.isSuccess() && StrUtil.isNotBlank(result.getMessage())) {
            throw new RuntimeException(result.getMessage());
        }
        return JSON.parseObject(result.getBody(), responseType);
    }

    /**
     * 获取内容
     *
     * @param bytes
     * @return
     */
    private static String byteToString(byte[] bytes) {
        if (Objects.nonNull(bytes)) {
            return new String(bytes, Charset.forName("utf-8"));
        }
        return StrUtil.EMPTY;
    }

    /**
     * 公共请求调用
     *
     * @param request
     * @return
     */
    private static OkHttpClientResult commonRequest(Request request) {
        return OkHttpClientBuilder.syncResponse(request);
    }

    public static String buildGetUrlWithParams(String json) {
        Map<String, String> map = JSON.parseObject(json, Map.class);
        // 将参数转换为URL编码的查询字符串
        String queryParam = map.entrySet().stream()
                .map(entry -> entry.getKey() + "=" + encodeURIComponent(entry.getValue()))
                .collect(Collectors.joining("&"));

        return queryParam;
    }

    private static String encodeURIComponent(String value) {
        try {
            return URLEncoder.encode(value, StandardCharsets.UTF_8.toString());
        } catch (Exception e) {
            throw new RuntimeException("Error encoding URL parameter", e);
        }
    }
}
